#pragma once
#include "api.hpp"
#include <string>

namespace opengl {

class shader {
public:
    /* Constructors */
    OPENGLAPI shader();                        // Declare an empty shader but does not create it
    OPENGLAPI shader(u32 type);                // Create a shader of a specific type
    OPENGLAPI shader(const shader &) = delete; // Use copy_from instead
    OPENGLAPI shader(shader &&other);          // Move constructor
    OPENGLAPI shader(u32 type,
                     const char *src);                      // Create and compile a shader of a
                                                            // specific type with source code
    OPENGLAPI static shader copy_from(const shader &other); // Create a new shader by copying from another shader
    OPENGLAPI static shader from_file(u32 type,
                                      const char *filename); // Create and compile shader from a file

    /* Member functions */
    OPENGLAPI void set_source(const char *src) const; // Set the source code of the shader
    OPENGLAPI bool compile() const;                   // Compile the shader and return true if successful
    OPENGLAPI std::string get_error() const;          // Check if there was an error during compilation

    /* Operator overloads */
    OPENGLAPI shader &operator=(const shader &) = delete; // Use copy_from instead
    OPENGLAPI shader &operator=(shader &&other);          // Move assignment operator

    /* Destructor */
    OPENGLAPI ~shader(); // Delete the shader if it was created

public:
    enum type : u32 {
        vertex_shader = 0x8B31,
        fragment_shader = 0x8B30,
        geometry_shader = 0x8DD9,
        tess_control_shader = 0x8E88,
        tess_evaluation_shader = 0x8E87,
        compute_shader = 0x91B9,
    };

public:
    u32 id; // OpenGL shader ID
};

} // namespace opengl